import pandas as pd
import os
from typing import Tuple, List, Dict, Any
import logging
import numpy as np
from project_paths import PROJECT_ROOT

logger = logging.getLogger(__name__)

class FileHandler:
    def __init__(self):
        # 获取当前文件所在目录的路径

        
        # 设置数据目录
        self.data_dir = os.path.join(PROJECT_ROOT, 'data')
        if not os.path.exists(self.data_dir):
            os.makedirs(self.data_dir)
        
        # 设置文件路径
        self.orders_file = os.path.join(self.data_dir, 'orders.csv')
        self.trades_file = os.path.join(self.data_dir, 'trades.csv')
        
        # 初始化文件
        self._init_files()
    
    def _init_files(self):
        """初始化必要的文件结构"""
        # 初始化orders.csv
        if not os.path.exists(self.orders_file) or os.path.getsize(self.orders_file) == 0:
            orders_df = pd.DataFrame(columns=[
                'Order ID', 'Symbol', 'Side', 'Type', 'Quantity', 'Filled',
                'Quantity Left', 'Limit', 'Stop', 'Avg Fill Price', 'Status',
                'Open Time', 'Close Time', 'Duration', 'Commission', 'Expiration',
                'Multiplier'
            ])
            orders_df.to_csv(self.orders_file, index=False)
        
        # 初始化trades.csv
        if not os.path.exists(self.trades_file) or os.path.getsize(self.trades_file) == 0:
            trades_df = pd.DataFrame(columns=[
                'trade_id',
                'symbol', 'open_datetime', 'close_datetime', 'open_price', 'open_qty',
                'close_price', 'close_qty', 'direction', 'open_order_type', 'trade_type',
                'point_profit_per_lot', 'total_points', 'gross_profit', 'net_profit',
                'commission', 'holding_time', 'nth_trade', 'session',
                'max_floating_profit_points', 'max_floating_profit_dollars',
                'max_floating_loss_points', 'max_floating_loss_dollars',
                'entry_reason', 'exit_reason', 'stop_loss_price', 'stop_loss_reason',
                'take_profit_price', 'take_profit_reason'
            ])
            trades_df.to_csv(self.trades_file, index=False)
    
    def read_orders(self) -> pd.DataFrame:
        """读取订单数据"""
        if not os.path.exists(self.orders_file) or os.path.getsize(self.orders_file) == 0:
            return pd.DataFrame()
        return pd.read_csv(self.orders_file)
    
    def read_trades(self) -> pd.DataFrame:
        """读取交易数据"""
        if not os.path.exists(self.trades_file) or os.path.getsize(self.trades_file) == 0:
            return pd.DataFrame()
        return pd.read_csv(self.trades_file)
    
    def append_orders(self, new_orders: pd.DataFrame) -> Tuple[pd.DataFrame, List[str]]:
        """添加新订单，返回新订单和重复订单ID列表"""
        if new_orders.empty:
            return pd.DataFrame(), []
        
        try:
            print('即将写入orders.csv，数据预览:')
            print(new_orders.head())
            print('列名:', new_orders.columns.tolist())
            
            # 确保数据类型正确
            new_orders['Order ID'] = new_orders['Order ID'].astype(str)
            new_orders['Symbol'] = new_orders['Symbol'].astype(str)
            new_orders['Side'] = new_orders['Side'].astype(str)
            new_orders['Type'] = new_orders['Type'].astype(str)
            new_orders['Quantity'] = pd.to_numeric(new_orders['Quantity'], errors='coerce').fillna(0)
            new_orders['Filled'] = pd.to_numeric(new_orders['Filled'], errors='coerce').fillna(0)
            new_orders['Quantity Left'] = pd.to_numeric(new_orders['Quantity Left'], errors='coerce').fillna(0)
            new_orders['Limit'] = pd.to_numeric(new_orders['Limit'], errors='coerce').fillna(0)
            new_orders['Stop'] = pd.to_numeric(new_orders['Stop'], errors='coerce').fillna(0)
            new_orders['Avg Fill Price'] = pd.to_numeric(new_orders['Avg Fill Price'], errors='coerce').fillna(0)
            new_orders['Status'] = new_orders['Status'].astype(str)
            new_orders['Commission'] = pd.to_numeric(new_orders['Commission'], errors='coerce').fillna(0)
            new_orders['Multiplier'] = pd.to_numeric(new_orders['Multiplier'], errors='coerce').fillna(1.0)
            
            # 如果文件不存在或为空，写入表头
            if not os.path.exists(self.orders_file) or os.path.getsize(self.orders_file) == 0:
                new_orders.to_csv(self.orders_file, index=False)
                print("创建新文件并写入表头")
            else:
                # 追加模式写入，不包含表头
                new_orders.to_csv(self.orders_file, mode='a', header=False, index=False)
                print("追加数据到现有文件")
                
        except Exception as e:
            print(f"Error writing orders.csv: {e}")
            import traceback
            traceback.print_exc()
            raise
        
        return new_orders, []
    
    def append_trades(self, new_trades: pd.DataFrame) -> Tuple[pd.DataFrame, List[str]]:
        """添加新交易，返回新交易和重复交易ID列表"""
        if new_trades.empty:
            return pd.DataFrame(), []

        print("new_trades: ", new_trades)

        # 读取现有交易
        existing_trades = self.read_trades()
        
        # 生成交易ID（使用标的、手数、开平仓时间和价格作为唯一标识）
        new_trades['trade_id'] = (new_trades['symbol'].astype(str) + '_' + 
                                new_trades['open_qty'].astype(str) + '_' +
                                new_trades['open_datetime'].astype(str) + '_' + 
                                new_trades['open_price'].astype(str) + '_' +
                                new_trades['close_datetime'].astype(str) + '_' +
                                new_trades['close_price'].astype(str))
        
        # 找出重复的交易ID
        duplicate_ids = []
        if not existing_trades.empty:
            existing_trades['trade_id'] = existing_trades['open_datetime'].astype(str) + '_' + existing_trades['close_datetime'].astype(str)
            duplicate_ids = new_trades[new_trades['trade_id'].isin(existing_trades['trade_id'])]['trade_id'].tolist()
        # 打印重复交易信息
        if duplicate_ids:
            print("\n=== 发现重复交易 ===")
            print(f"重复交易数量: {len(duplicate_ids)}")
            duplicate_trades = new_trades[new_trades['trade_id'].isin(duplicate_ids)]
            print("\n重复交易详情:")
            for _, trade in duplicate_trades.iterrows():
                print(f"\n交易ID: {trade['trade_id']}")
                print(f"标的: {trade['symbol']}")
                print(f"方向: {trade['direction']}")
                print(f"开仓时间: {trade['open_datetime']}")
                print(f"开仓价格: {trade['open_price']}")
                print(f"平仓时间: {trade['close_datetime']}")
                print(f"平仓价格: {trade['close_price']}")
                print(f"交易手数: {trade['open_qty']}")
        # 过滤掉重复的交易
        new_trades = new_trades[~new_trades['trade_id'].isin(duplicate_ids)]
        
        # 合并并保存
        if not new_trades.empty:
            all_trades = pd.concat([existing_trades, new_trades], ignore_index=True)
            all_trades.to_csv(self.trades_file, index=False)
        
        return new_trades, duplicate_ids
    
    def get_latest_order_time(self):
        """获取最新订单时间"""
        if not os.path.exists(self.orders_file):
            return None
        orders_df = pd.read_csv(self.orders_file)
        if orders_df.empty:
            return None
        return orders_df['Open Time'].max()

    def is_order_duplicate(self, order: pd.Series) -> bool:
        """检查订单是否已存在"""
        try:
            # 读取现有订单
            existing_orders_df = self.read_orders()
            if existing_orders_df.empty:
                return False
            
            # 将字符串字段转换为小写进行比较
            order_id = str(order['Order ID']).lower()
            symbol = str(order['Symbol']).lower()
            side = str(order['Side']).lower()
            order_type = str(order['Type']).lower()
            status = str(order['Status']).lower()
            filled = str(order['Filled']).lower()
            avg_fill_price = str(order['Avg Fill Price']).lower()
            
            # 检查关键字段是否匹配（忽略大小写）
            duplicate = existing_orders_df[
                (existing_orders_df['Order ID'].astype(str).str.lower() == order_id) &
                (existing_orders_df['Symbol'].astype(str).str.lower() == symbol) &
                (existing_orders_df['Side'].astype(str).str.lower() == side) &
                (existing_orders_df['Type'].astype(str).str.lower() == order_type) &
                (existing_orders_df['Status'].astype(str).str.lower() == status) &
                (existing_orders_df['Filled'].astype(str).str.lower() == filled) &
                (existing_orders_df['Avg Fill Price'].astype(str).str.lower() == avg_fill_price)
            ]
            
            return not duplicate.empty
            
        except Exception as e:
            logger.error(f"检查订单重复时出错: {str(e)}")
            return False

    def is_trade_duplicate(self, trade: Dict) -> bool:
        """检查交易是否已存在"""
        try:
            # 读取现有交易记录
            existing_trades_df = self.read_trades()
            if existing_trades_df.empty:
                return False
            
            # 将字符串字段转换为小写进行比较
            open_datetime = str(trade['open_datetime']).lower()
            close_datetime = str(trade['close_datetime']).lower()
            symbol = str(trade['symbol']).lower()
            open_price = str(trade['open_price']).lower()
            close_price = str(trade['close_price']).lower()
            
            # 检查关键字段是否匹配（忽略大小写）
            duplicate = existing_trades_df[
                (existing_trades_df['open_datetime'].astype(str).str.lower() == open_datetime) &
                (existing_trades_df['close_datetime'].astype(str).str.lower() == close_datetime) &
                (existing_trades_df['symbol'].astype(str).str.lower() == symbol) &
                (existing_trades_df['open_price'].astype(str).str.lower() == open_price) &
                (existing_trades_df['close_price'].astype(str).str.lower() == close_price)
            ]
            
            return not duplicate.empty
            
        except Exception as e:
            logger.error(f"检查交易重复时出错: {str(e)}")
            return False